using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace Freshbooks.Client
{
    public class InvoiceCommand
    {
        public static string GetInvoiceByEmailXml(Invoice invoice)
        {
            string input;
            using (MemoryStream w = new MemoryStream())
            {
                using (XmlTextWriter writer = new XmlTextWriter(w, Encoding.UTF8))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("request");
                    writer.WriteStartAttribute("method");
                    writer.WriteValue("invoice.sendByEmail");
                    writer.WriteEndAttribute();
                    writer.WriteStartElement("invoice");
                    writer.WriteStartElement("invoice_id");
                    writer.WriteValue(invoice.InvoiceFreshBooksId);
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Flush();
                }
                input = Encoding.UTF8.GetString(w.GetBuffer());
                w.Close();
            }
            Regex.Replace(input, "<.* />", "");
            return input;
        }

        public static string GetInvoiceByEmailXml(Invoice invoice, string subject, string message)
        {
            if (string.IsNullOrEmpty(subject) || string.IsNullOrEmpty(message))
            {
                throw new Exception("Subject and Message both must be defined");
            }

            string input;
            using (MemoryStream w = new MemoryStream())
            {
                using (XmlTextWriter writer = new XmlTextWriter(w, Encoding.UTF8))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("request");
                    writer.WriteStartAttribute("method");
                    writer.WriteValue("invoice.sendByEmail");
                    writer.WriteEndAttribute();
                    writer.WriteStartElement("invoice");
                    writer.WriteStartElement("invoice_id");
                    writer.WriteValue(invoice.InvoiceFreshBooksId);
                    writer.WriteEndElement();

                    writer.WriteStartElement("subject");
                    writer.WriteValue(subject);
                    writer.WriteEndElement();

                    writer.WriteStartElement("message");
                    writer.WriteValue(message);
                    writer.WriteEndElement();

                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Flush();
                }
                input = Encoding.UTF8.GetString(w.GetBuffer());
                w.Close();
            }
            Regex.Replace(input, "<.* />", "");
            return input;
        }

        public string GetInvoiceCreationXml(Invoice invoice)
        {
            string input;
            using (MemoryStream w = new MemoryStream())
            {
                using (XmlTextWriter writer = new XmlTextWriter(w, Encoding.UTF8))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("request");
                    writer.WriteStartAttribute("method");
                    writer.WriteValue("invoice.create");
                    writer.WriteEndAttribute();
                    writer.WriteStartElement("invoice");
                    writer.WriteStartElement("client_id");
                    writer.WriteValue(invoice.ClientID);
                    writer.WriteEndElement();
                    writer.WriteStartElement("number");
                    writer.WriteValue(invoice.Number);
                    writer.WriteEndElement();
                    writer.WriteStartElement("status");
                    writer.WriteValue(invoice.Status.ToString());
                    writer.WriteEndElement();
                    writer.WriteStartElement("date");
                    writer.WriteValue(invoice.Date.ToString("yyyy-MM-dd"));
                    writer.WriteEndElement();
                    writer.WriteStartElement("po_number");
                    writer.WriteValue(invoice.PurchaseOrderNumber);
                    writer.WriteEndElement();
                    writer.WriteStartElement("discount");
                    writer.WriteValue(invoice.Discount);
                    writer.WriteEndElement();
                    writer.WriteStartElement("notes");
                    writer.WriteValue(invoice.Notes);
                    writer.WriteEndElement();
                    writer.WriteStartElement("terms");
                    writer.WriteValue(invoice.Terms);
                    writer.WriteEndElement();
                    writer.WriteStartElement("first_name");
                    writer.WriteValue(invoice.FirstName);
                    writer.WriteEndElement();
                    writer.WriteStartElement("last_name");
                    writer.WriteValue(invoice.LastName);
                    writer.WriteEndElement();
                    writer.WriteStartElement("organization");
                    writer.WriteValue(invoice.Organization);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_street1");
                    writer.WriteValue(invoice.Street1);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_street2");
                    writer.WriteValue(invoice.Street2);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_city");
                    writer.WriteValue(invoice.City);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_state");
                    writer.WriteValue(invoice.State);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_country");
                    writer.WriteValue(invoice.Country);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_code");
                    writer.WriteValue(invoice.Code);
                    writer.WriteEndElement();

                    writer.WriteStartElement("currency_code");
                    writer.WriteValue(invoice.CurrencyCode);
                    writer.WriteEndElement();


                    writer.WriteStartElement("lines");
                    foreach (InvoiceItem item in invoice.InvoceItems)
                    {
                        writer.WriteStartElement("line");
                        writer.WriteStartElement("name");
                        writer.WriteValue(item.Name);
                        writer.WriteEndElement();
                        writer.WriteStartElement("description");
                        writer.WriteValue(item.Description);
                        writer.WriteEndElement();
                        writer.WriteStartElement("unit_cost");
                        writer.WriteValue(item.UnitCost);
                        writer.WriteEndElement();
                        writer.WriteStartElement("quantity");
                        writer.WriteValue(item.Quantity);
                        writer.WriteEndElement();
                        writer.WriteStartElement("tax1_name");
                        writer.WriteValue(item.Tax1Name);
                        writer.WriteEndElement();
                        writer.WriteStartElement("tax2_name");
                        writer.WriteValue(item.Tax2Name);
                        writer.WriteEndElement();
                        writer.WriteStartElement("tax1_percent");
                        writer.WriteValue(item.Tax1Percent);
                        writer.WriteEndElement();
                        writer.WriteStartElement("tax2_percent");
                        writer.WriteValue(item.Tax2Percent);
                        writer.WriteEndElement();
                        writer.WriteEndElement();
                    }
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Flush();
                }
                input = Encoding.UTF8.GetString(w.GetBuffer());
                w.Close();
            }
            Regex.Replace(input, "<.* />", "");
            return input;
        }

        public static string GetInvoiceDeleteXml(Invoice invoice)
        {
            string input;
            using (MemoryStream w = new MemoryStream())
            {
                using (XmlTextWriter writer = new XmlTextWriter(w, Encoding.UTF8))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("request");
                    writer.WriteStartAttribute("method");
                    writer.WriteValue("invoice.delete");
                    writer.WriteEndAttribute();
                    writer.WriteStartElement("invoice");
                    writer.WriteStartElement("invoice_id");
                    writer.WriteValue(invoice.InvoiceFreshBooksId);
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Flush();
                }
                input = Encoding.UTF8.GetString(w.GetBuffer());
                w.Close();
            }
            Regex.Replace(input, "<.* />", "");
            return input;
        }

        public static string GetInvoiceUpdateXml(Invoice invoice)
        {
            string input;
            using (MemoryStream w = new MemoryStream())
            {
                using (XmlTextWriter writer = new XmlTextWriter(w, Encoding.UTF8))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("request");
                    writer.WriteStartAttribute("method");
                    writer.WriteValue("invoice.update");
                    writer.WriteEndAttribute();
                    writer.WriteStartElement("invoice");
                    writer.WriteStartElement("invoice_id");
                    writer.WriteValue(invoice.InvoiceFreshBooksId);
                    writer.WriteEndElement();
                    writer.WriteStartElement("client_id");
                    writer.WriteValue(invoice.ClientID);
                    writer.WriteEndElement();
                    writer.WriteStartElement("number");
                    writer.WriteValue(invoice.Number);
                    writer.WriteEndElement();
                    writer.WriteStartElement("status");
                    writer.WriteValue(invoice.Status.ToString());
                    writer.WriteEndElement();
                    writer.WriteStartElement("date");
                    writer.WriteValue(invoice.Date.ToString("yyyy-MM-dd"));
                    writer.WriteEndElement();
                    writer.WriteStartElement("po_number");
                    writer.WriteValue(invoice.PurchaseOrderNumber);
                    writer.WriteEndElement();
                    writer.WriteStartElement("discount");
                    writer.WriteValue(invoice.Discount);
                    writer.WriteEndElement();
                    writer.WriteStartElement("notes");
                    writer.WriteValue(invoice.Notes);
                    writer.WriteEndElement();
                    writer.WriteStartElement("terms");
                    writer.WriteValue(invoice.Terms);
                    writer.WriteEndElement();
                    writer.WriteStartElement("first_name");
                    writer.WriteValue(invoice.FirstName);
                    writer.WriteEndElement();
                    writer.WriteStartElement("last_name");
                    writer.WriteValue(invoice.LastName);
                    writer.WriteEndElement();
                    writer.WriteStartElement("organization");
                    writer.WriteValue(invoice.Organization);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_street1");
                    writer.WriteValue(invoice.Street1);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_street2");
                    writer.WriteValue(invoice.Street2);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_city");
                    writer.WriteValue(invoice.City);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_state");
                    writer.WriteValue(invoice.State);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_country");
                    writer.WriteValue(invoice.Country);
                    writer.WriteEndElement();
                    writer.WriteStartElement("p_code");
                    writer.WriteValue(invoice.Code);
                    writer.WriteEndElement();

                    writer.WriteStartElement("currency_code");
                    writer.WriteValue(invoice.CurrencyCode);
                    writer.WriteEndElement();

                    writer.WriteStartElement("lines");
                    foreach (InvoiceItem item in invoice.InvoceItems)
                    {
                        writer.WriteStartElement("line");
                        writer.WriteStartElement("name");
                        writer.WriteValue(item.Name);
                        writer.WriteEndElement();
                        writer.WriteStartElement("description");
                        writer.WriteValue(item.Description);
                        writer.WriteEndElement();
                        writer.WriteStartElement("unit_cost");
                        writer.WriteValue(item.UnitCost);
                        writer.WriteEndElement();
                        writer.WriteStartElement("quantity");
                        writer.WriteValue(item.Quantity);
                        writer.WriteEndElement();
                        writer.WriteStartElement("tax1_name");
                        writer.WriteValue(item.Tax1Name);
                        writer.WriteEndElement();
                        writer.WriteStartElement("tax2_name");
                        writer.WriteValue(item.Tax2Name);
                        writer.WriteEndElement();
                        writer.WriteStartElement("tax1_percent");
                        writer.WriteValue(item.Tax1Percent);
                        writer.WriteEndElement();
                        writer.WriteStartElement("tax2_percent");
                        writer.WriteValue(item.Tax2Percent);
                        writer.WriteEndElement();
                        writer.WriteEndElement();
                    }
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Flush();
                }
                input = Encoding.UTF8.GetString(w.GetBuffer());
                w.Close();
            }
            Regex.Replace(input, "<.* />", "");
            return input;
        }

        public static string GetCreateXml(Invoice invoice)
        {
            string input;
            using (MemoryStream w = new MemoryStream())
            {
                using (XmlTextWriter writer = new XmlTextWriter(w, Encoding.UTF8))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("request");
                    writer.WriteStartAttribute("method");
                    writer.WriteValue("invoice.update");
                    writer.WriteEndAttribute();
                    writer.WriteStartElement("invoice");
                    writer.WriteStartElement("invoice_id");
                    writer.WriteValue(invoice.InvoiceFreshBooksId);
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Flush();
                }
                input = Encoding.UTF8.GetString(w.GetBuffer());
                w.Close();
            }
            Regex.Replace(input, "<.* />", "");
            return input;
        }
    }
}